﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ServiceMonitor.Utils
{


    public class PortProcessTerminator
    {
        /// <summary>
        /// 通过端口号强制终止进程及其子进程
        /// </summary>
        /// <param name="port">要关闭的端口号</param>
        /// <returns>操作结果消息</returns>
        public static string KillProcessByPort(int port)
        {
            if (port < 1 || port > 65535)
                return "错误：端口号无效 (必须介于 1-65535)";
            try
            {
                // 1. 获取监听指定端口的进程ID
                int processId = GetProcessIdByPort(port);

                if (processId == -1)
                    return $"端口 {port} 未被任何进程监听";

                // 2. 终止进程树
                KillProcessTree(processId);
                return $"成功终止进程(PID:{processId})及其子进程，释放端口 {port}";
            }
            catch (Exception ex)
            {
                return $"错误：{ex.GetType().Name} - {ex.Message}";
            }
        }
        /// <summary>
        /// 使用 netstat 获取监听端口的进程ID
        /// </summary>
        private static int GetProcessIdByPort(int port)
        {
            using (Process netstatProcess = new Process())
            {
                netstatProcess.StartInfo.FileName = "netstat.exe";
                netstatProcess.StartInfo.Arguments = "-ano";
                netstatProcess.StartInfo.UseShellExecute = false;
                netstatProcess.StartInfo.RedirectStandardOutput = true;
                netstatProcess.StartInfo.CreateNoWindow = true;

                netstatProcess.Start();
                string output = netstatProcess.StandardOutput.ReadToEnd();
                netstatProcess.WaitForExit();
                // 解析输出结果
                string[] lines = output.Split('\n');

                foreach (string line in lines)
                {
                    // 寻找监听状态的目标端口
                    if (line.Contains("LISTENING") && line.Contains($":{port}"))
                    {
                        // 按空白分割行
                        string[] parts = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                        // 最后一个元素是进程ID
                        if (parts.Length > 4 && int.TryParse(parts[4], out int pid))
                        {
                            return pid;
                        }
                    }
                }
            }
            return -1; // 未找到
        }
        /// <summary>
        /// 终止进程及其所有子进程
        /// </summary>
        private static void KillProcessTree(int processId)
        {
            // 终止所有子进程
            using (Process taskKill = new Process())
            {
                taskKill.StartInfo.FileName = "taskkill.exe";
                taskKill.StartInfo.Arguments = $"/PID {processId} /T /F";
                taskKill.StartInfo.UseShellExecute = false;
                taskKill.StartInfo.CreateNoWindow = true;

                taskKill.Start();
                taskKill.WaitForExit();
            }
        }
    }

}
